﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace PrototypeZGame
{
    public class Terrain
    {
        private World world;
        
        public Field[,] field;
        private Field lastMouseOver;
        public int X, Y;


        public Terrain(Texture2D srcTexture, World world)
        {
            X = srcTexture.Bounds.Width;
            Y = srcTexture.Bounds.Height;
            this.world = world;
            world.terrain = this;
            field = new Field[X, Y];

            for (int i = 0; i < X; i++)
            {
                for (int j = 0; j < Y; j++)
                {
                    field[i, j] = new Field(i, j, world);
                }
            }

            Color[,] color = GameHelper.TextureTo2DArray(srcTexture);
            for (int i = 0; i < srcTexture.Bounds.Width; i++)
            {
                for (int j = 0; j < srcTexture.Bounds.Height; j++)
                {
                    field[i, j].setFieldTypeFromColor(color[i, j]);
                }
            }            
        }

        public void Clear()
        {
            foreach (Field f in field)
            {
                f.Clear();
            }
        }

        public void Draw(int x, int y, int x2, int y2)
        {
            if (x < 0) x = 0;
            if (y < 0) y = 0;
            x2++;
            y2++;
            if (x2 > X) x2 = X;
            if (y2 > Y) y2 = Y;
            int i,j;
            
            for (i = x; i < x2; i++)
            {
                for (j = y; j < y2; j++)
                {
                    field[i, j].Draw();
                }
            }
        }        

        public void MouseOver(Vector2 mouseWorldPosition)
        {
            if (lastMouseOver != null)
            {
                lastMouseOver.mouseOver = false;
            }

            mouseWorldPosition /= world.fieldResolution;
            int x, y;
            x = (int)mouseWorldPosition.X;
            y = (int)mouseWorldPosition.Y;
            if (x >=0 && x < X && y>=0 && y < Y)
            {
                field[x, y].mouseOver = true;
                lastMouseOver = field[x, y];
            }
        }

        public Field worldPositionToField(Vector2 worldPosition)
        {
            worldPosition /= world.fieldResolution;
            int x, y;
            x = (int)worldPosition.X;
            y = (int)worldPosition.Y;
            if (isPositionValid(x, y))
            {
                return field[x, y];
            }
            else
            {
                return null;
            }
        }

        public bool putOn(Actor actor)
        {
            return field[actor.position.x, actor.position.y].putOn(actor);
        }

        public bool takeFrom(Actor actor)
        {
            return field[actor.position.x, actor.position.y].takeFrom(actor);
        }

        public Result blocking(int x, int y)
        {
            if (isPositionValid(x,y))
            {
                return field[x, y].blocking;
            }
            else
            {
                return Result.BlockingField;
            }            
        }

        public Result blocking(Vec2 v)
        {
            return blocking(v.x, v.y);
        }

        public bool isPositionValid(int x, int y)
        {
            return (x >= 0 && x < X && y >= 0 && y < Y);
        }

        public bool isPositionValid(Vec2 v)
        {
            return isPositionValid(v.x, v.y);
        }



        public int moveCost(Vec2 v)
        {
            if (v.x >= 0 && v.x < X && v.y >= 0 && v.y < Y)
            {
                return field[v.x, v.y].moveCost;
            }
            else
            {
                return int.MaxValue;
            }
        }

        public Field getField(Vec2 position)
        {
            return field[position.x, position.y];
        }
    }
}
